
//
//  ApiBaseManager.swift
//  SearchGithubUserInfo
//
//  Created by menhao on 17/5/15.
//  Copyright © 2017年 menhao. All rights reserved.
//
import Foundation
import Alamofire
import SVProgressHUD


@objc enum ManagerRequestMethod : Int {
    
    case RequestMethodRestGET//, HEAD, , PUT, PATCH, DELETE, TRACE, CONNECT
    case RequestMethodRestPOST
}

//reform data for containers(Array/Dictionary) to contain strings for view to display
@objc protocol DataAdaptorProtocol {
    func reformResponseData(responseData: AnyObject, withManager: ApiBaseManager) -> AnyObject?
}


//every children class need to conform to this protocol
@objc protocol ApiManagerProtocol {
    
    var requestMethod: ManagerRequestMethod {get }
    var responseDataType: APIResponseDataType {get}
    @objc optional
    var isShowNodata:Bool{get}
     @objc optional
    var isShowNoNet:Bool{get}
     @objc optional
    var isShowError:Bool{get}
     @objc optional
    var isShowHud:Bool{get}
     @objc optional
    var isHomePage:Bool{get}
    
}


class ApiBaseManager: SessionDelegate {
    
    //MARK: - functions
    func loadData(){
   

        guard let urlProvider = urlProviderDelegate else {
            return
        }
        
        let urlPath = getUrlString(urlProvider: urlProvider)
        var header = [String : String]()
        let parameters = urlProvider.parametersForManager(manager: self)
        let token = UserDefaults.standard.object(forKey: "token") as? String
        let userid = UserDefaults.standard.object(forKey: "userId") as? String
        let apiid = UserDefaults.standard.object(forKey: "cookie_id") as? String
        if token != nil && token != "" && userid != nil && userid != ""{
           header = ["token":token!,"platformCode":"5","userId":userid!]
        }else{
           header = urlProvider.headerForManager!(manager: self)!
        }
        header["MerchantCode"] = "026"
        header["X-APP-CID"] = UIDevice.current.identifierForVendor?.uuidString
        header["X-APP-AGENT"] = NSString.getAgentInfo()
        header["X-PROTOCOL"] = "JAVAAPI"
        header["X-APP-IP"] = MCGetIPAdress.getIPAddress(true)
        if apiid != nil && apiid != "" {
            header["APIID"] = apiid
        }
        
        debugPrint(urlPath,"---------")
     
        
        var requestMethod = ManagerRequestMethod.RequestMethodRestGET
        var responseDataType = APIResponseDataType.Json
        if let _ = requestCustomizeDelegate {
            requestMethod = requestCustomizeDelegate!.requestMethod
            responseDataType = requestCustomizeDelegate!.responseDataType
        }

       
        let status = ApiBaseManager.networkIsReachability()
        if status == false {
            SVProgressHUD.showInfo(withStatus: "请检查您的网络！")
            NotificationCenter.default.post(name: NSNotification.Name.NetworkIsReachability, object: nil)
            self.cancellAllRequests()
            return
        }

        var requestId: NSNumber
        switch requestMethod {
            
        case .RequestMethodRestGET:
            
            requestId = ApiProxy.sharedInstance.makeRestGetRequestForUrl(url: urlPath, parameters: parameters, responseDataType: responseDataType,header: header, successedCallBack: requestSuccessed, failedCallBack: requestFailed)
            
        case .RequestMethodRestPOST:
            
            requestId = ApiProxy.sharedInstance.makeRestPostRequestForUrl(url: urlPath, parameters: parameters, responseDataType: responseDataType,header:header, successedCallBack: requestSuccessed, failedCallBack: requestFailed)
        }
       
        allRequestIds.append(requestId)

    }
   class func networkIsReachability() -> Bool{
        return (NetworkReachabilityManager()?.isReachable)!
    }
    func upLoadImageRequest(data: [Data], name: [String]){
        guard let urlProvider = urlProviderDelegate else {
            return
        }
        let urlString = getUrlString(urlProvider: urlProvider)
        let parameters = urlProvider.parametersForManager(manager: self)
        ApiProxy.sharedInstance.upLoad(urlString: urlString,data: data,name: name, parameters: parameters, successCallBack: requestSuccessed, failedCallBack: requestFailed)

    }

    func getUrlString(urlProvider:ApiManagerProvider) -> String{
        
        cleanResponseData()
        let urlComponent = urlProvider.urlPathComponentForManager(manager: self)
        var urlString = "" //接口测试服务器地址
        let str = UserDefaults.standard.object(forKey: "BASEURL") as? String
        if str == nil {
            if testApi == "testApi"{
                if xianluaddr == ""{
                    urlString = MCTEST_BASE_API + urlComponent
                }else{
                    urlString = xianluaddr + urlComponent
                }
                
            }else{
                urlString = DEFAULTSEVERBASEURL + urlComponent
            }
           
            
        }else{
            urlString = str! + urlComponent
        }

        if urlString.isEmpty {
            return ""
        }
        return urlString
    }
    
    func getUrlTokenString() -> String{
        
        cleanResponseData()
        let urlComponent = "web-api/api/v4/get_new_token"
        var urlString = "" //接口测试服务器地址
        let str = UserDefaults.standard.object(forKey: "Base_API_Line") as! String
        urlString = str + urlComponent
   
        if urlString.isEmpty {
            return ""
        }
        return urlString
    }
    
    //clean data for new request
    func cleanResponseData() {
        ResponseRawData = nil
        ResponseError = nil
    }
    
    func cancellRequest(requestId: NSNumber) {
        
        guard let index = getRequestIndex(requestId: requestId) else {
            return
        }
        
        ApiProxy.sharedInstance.cancellRequestForId(requestId: requestId)
        allRequestIds.remove(at: index)
    }
    
   func cancellAllRequests() {
        
        ApiProxy.sharedInstance.cancellAllRequest()
        allRequestIds.removeAll()

    }
    
    func removeRequestId(requestId: NSNumber) {
        
        guard let index = getRequestIndex(requestId: requestId) else {
            return
        }
        
        allRequestIds.remove(at: index)
    }
    
    func getRequestIndex(requestId: NSNumber) -> Int? {
        for (index, value) in allRequestIds.enumerated() {
            if value == requestId {
                return index
            }
        }
        
        return nil
    }
    
    //called after request successed
    func getReformedDataByAdaptor(adaptor: DataAdaptorProtocol) -> AnyObject? {
        if let _ = self.ResponseRawData {
            return adaptor.reformResponseData(responseData: self.ResponseRawData!, withManager: self)
        }
        
        return self.ResponseRawData
    }

    private
    //request callbacks
    func requestSuccessed(responseObj: AnyObject, requestId: NSNumber) {

        
        if requestCustomizeDelegate?.isShowHud == true {
            SVProgressHUD.dismiss()
            BKIndicationView.dismiss()
        }
        

        
        let respone = responseObj as? DataResponse<Any>
        if respone == nil {
            if let _ = apiCallBackDelegate {
                apiCallBackDelegate?.managerCallAPIDidFailed(manager: self, errorCode: nil)
                
            }
            return
        }
     
        let dic = respone?.result.value as! Dictionary<String, AnyObject>
        
        debugPrint("responseData==========",dic)
        
        if dic.keys.contains("data") {
            //含有data
            ResponseRawData = dic["data"]
        }else if(dic.keys.contains("Data") ) {
            //不含data
            ResponseRawData = dic["Data"]
        }else{
            
        }
        
        var resultStr :String?
        
        if dic.keys.contains("message") {
            //含有code
            resultStr = dic["message"] as? String
        }else if dic.keys.contains("Msg"){
            //不含code
            resultStr = dic["Msg"] as? String
        }
        responseMessage = resultStr
        
        ResponseHeader = respone?.response?.allHeaderFields as AnyObject
        
        var result = NSNumber();
        
        if dic.keys.contains("code") {
            //含有code
            result = dic["code"] as! NSNumber
        }else if dic.keys.contains("Code"){
            //不含code
            result = dic["Code"] as! NSNumber
        }
        
            if result == 200 {
                
                showInfo(dic: dic)
                if let _ = apiCallBackDelegate {
                    apiCallBackDelegate?.managerCallAPIDidSuccess(manager: self)
                }
            }else {

            if result == 401 || result == 407 || result == 405 || result == 402 || result == 403 || result == 404{
                let token = UserDefaults.standard.object(forKey: "token") as? String
                let userid = UserDefaults.standard.object(forKey: "userId") as? String
                SVProgressHUD.setDefaultStyle(.dark)
                SVProgressHUD.showInfo(withStatus:"您的登录已失效，请重新登录")

                if token == nil || token == "" && userid == nil || userid == "" {
                    if let _ = apiCallBackDelegate {
                        apiCallBackDelegate?.managerCallAPIDidFailed(manager: self, errorCode: ["code":result])

                    }
                    return
                }
                cancellAllRequests()
                NotificationCenter.default.post(name: NSNotification.Name(rawValue: "PRESENT_LOGINVC_NOTICATION"), object: nil)
            }else{
                
                showInfo(dic: dic)
                if let _ = apiCallBackDelegate {
                    
                    apiCallBackDelegate?.managerCallAPIDidFailed(manager: self, errorCode: ["code":result])
                }
                return
            }
        }
        removeRequestId(requestId: requestId)
       
    }
    func showInfo(dic:Dictionary<String, Any>){
        if responseMessage != nil {
            
            if(responseMessage?.contains("验证码"))!||(responseMessage?.contains("失败"))!||(responseMessage?.contains("成功"))! || (responseMessage?.contains("请求"))! ||  (responseMessage?.contains("token"))! ||  (responseMessage?.contains("查询"))!||(responseMessage?.contains("参数"))!||(responseMessage?.contains("测试账号无法进入第三方游戏平台"))!||(responseMessage?.contains("???"))!{
            } else {//                             测试账号无法进入第三方游戏平台
                

                if requestCustomizeDelegate?.isShowHud == true {
                    SVProgressHUD.setDefaultStyle(.dark)
                    var resultStr = ""
                    
                    if dic.keys.contains("message") {
                        //含有message
                        resultStr = dic["message"] as! String
                    }else{
                        //不含message
                        resultStr = dic["Msg"] as! String
                    }
                    
                    let resultStrr = NSString.init(string: resultStr)
                    resultStrr.replacingOccurrences(of: " ", with: "")
                    
                    if resultStrr == ""{
                        
                    }else{
                        SVProgressHUD.showInfo(withStatus:resultStr)
                    }
                    
                }
            }
        }
    }
    func requestFailed(responseError: NSError, requestId: NSNumber) {
        if requestCustomizeDelegate?.isShowHud == true {
            SVProgressHUD.dismiss()
            BKIndicationView.dismiss()
        }
        ResponseError = responseError
        
        if requestCustomizeDelegate?.isShowError == true && requestCustomizeDelegate?.isHomePage == false{

            return
        }
        if let _ = apiCallBackDelegate {
            apiCallBackDelegate?.managerCallAPIDidFailed(manager: self, errorCode: ["code":responseError])

        }
        
        removeRequestId(requestId: requestId)
   
    }
 
////    #pragma mark 1.收到服务器相应
//    
//
//    override func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
//        
//    }
//    
//    
////    #pragma mark 2.服务器开始传输数据（一点一点返回，这个代理方法会被反复调用，返回 NSData 数据）
//    
//    override func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
//   
//        
//    }
//
////    #pragma mark 3.客户端接收数据完成的时候
//    
//    override func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, willCacheResponse proposedResponse: CachedURLResponse, completionHandler: @escaping (CachedURLResponse?) -> Void) {
//        
//    }
//  
    
   
    //MARK: - life cycle
    init(urlProvider: ApiManagerProvider?) {
        super.init()
        urlProviderDelegate = urlProvider
        
        if self is ApiManagerProtocol {
            requestCustomizeDelegate = self as? ApiManagerProtocol
        }
    }
 
    deinit {
        

    }
    
    //MARK: instance variables
    var ResponseRawData: AnyObject?
    var ResponseError: NSError?
    var allRequestIds = Array<NSNumber>()
    var ResponseHeader :AnyObject?
    var responseMessage :String?
    //delegates
    weak var apiCallBackDelegate: ApiManagerCallBackProtocol?
    weak var urlProviderDelegate: ApiManagerProvider?
    weak var requestCustomizeDelegate: ApiManagerProtocol?
}

